This notebook will contain analysis of the data saved in logfiles by the new module potting routine.
First, one must prepare the datafiles.
zip -uj Potting_Logs.zip /home/dominguez/cfangmeier/elog_git/logbooks/SiLab_Logbook/*/*_Config-*-*-*.zip
./PottingLog2JSON.py Potting_Logs.zip
Alternatively, You can just run the pre-prepared script to automate these steps. Note that you must give the script your t3 username as the first argument so it can execute the scp and ssh commands appropriately.
After running the above, the resulting json can be read in and processed.
In [1]:
%matplotlib notebook
from IPython.display import Markdown, display_markdown
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import gridspec
import numpy as np
import itertools
import collections
import json
import Quaternion
from datetime import datetime
plt.style.use('fivethirtyeight')
plt_cols = itertools.cycle([col['color'] for col in plt.rcParams['axes.prop_cycle']._left])
plt.rcParams['figure.figsize'] = [12,8]
In [2]:
dec = json.JSONDecoder()
with open('Potting_Logs.json','r') as f:
modules = dec.decode(f.read())
modules = {id_: data['potting'] for id_, data in modules.items() if 'potting' in data}
In [3]:
def net_phi(quat):
quat = [float(q) for q in quat]
quat = Quaternion.Quat(quat)
v = np.array([1,0,0])
v = quat.transform @ v
return np.arctan2(v[1],v[0]) * 180/np.pi
ss = ['| | Session ID | Module ID | Operator | Date | Time (min) | Chuck | Slot | Offset ($\mu$m) | $\phi_{HDI}$ | $\phi_{BBM}$ | $\phi_{net}$ | 4cm*$\sin(\phi_{net})$ ($\mu$m)|',
'|---|------------|-----------|----------|------|-----------:|------:|-----:|----------------:|-------------:|-------------:|-------------:|--------------------------------|']
sorted_keys = sorted(modules, key=lambda k: modules[k]['source_file'])
for i, module_id in enumerate(sorted_keys):
module = modules[module_id]
operator = module.get('operator_name','n/a').title()
try:
date = module['date']
except Exception:
date = "N/A"
time = module.get('time',0)
session_id = module['source_file']
chuck = int(module.get('chuck','N/A'))
slot = int(module.get('slot', 'N/A'))
bbm_center = [float(x) for x in module['BBM_center']][:2]
hdi_center = [float(x) for x in module['HDI_center']][:2]
offset = sum((x-y)**2 for x,y in zip(bbm_center, hdi_center))**.5
offset *= 1000
rot_bbm = net_phi(module['BBM_orient'])
rot_hdi = net_phi(module['HDI_orient'])
rot_net = abs(rot_bbm - rot_hdi)
edge_delta = 4*10000*np.sin(rot_net * (np.pi/180))
s = ("|{i}|{session_id}|{module_id}|{op}|{date}|{time}|{chuck:02d}|{slot:02d}|{offset:.03f}"
"|{rot_hdi:.03f}°|{rot_bbm:.03f}°|{rot_net:.03f}°|{edge_delta:.03f}|")
s = s.format(i=i+1, session_id=session_id, module_id=module_id, op=operator, date=date, time=time,
chuck=chuck, slot=slot, offset=offset, rot_hdi=rot_hdi,
rot_bbm=rot_bbm, rot_net=rot_net, edge_delta=edge_delta)
ss.append(s)
m = Markdown('\n'.join(ss))
In [4]:
ops = collections.defaultdict(int)
for module in modules.values():
op = module.get('operator_name','N/A').lower()
ops[op] += 1
fig = plt.figure()
ax = fig.gca()
ypos = list(range(len(ops)))
names, counts = zip(*ops.items())
ax.barh(ypos, counts, align='center', alpha=0.4, tick_label=names)
ax.set_xlim((0,max(counts)*1.2))
ax.set_xlabel('Modules Encapsulated')
plt.show()
display_markdown(m)
In [5]:
fig = plt.figure()
gs = gridspec.GridSpec(1, 3, width_ratios=[2.5, 1,.7])
ax_fid = fig.add_subplot(gs[0], adjustable='box', aspect=1)
ax_pot = fig.add_subplot(gs[1], adjustable='box', aspect=1)
for color, module_id in zip(plt_cols,list(modules.keys())[-15:]):
module = modules[module_id]
pts_local = []
for val in module['pot_lines'].values():
pts_local.append(val['local']['start'])
pts_local.append(val['local']['end'])
xs,ys,zs = zip(*pts_local)
ax_pot.plot(xs,ys, '.', label=module_id, color=color)
pts_local.clear()
for val in module['BBM_fids'].values():
pts_local.append(val['fid_pos'])
xs,ys,zs = zip(*pts_local)
ax_fid.plot(xs,ys, 'x', label=module_id, color=color)
pts_local.clear()
for val in module['HDI_fids'].values():
pts_local.append(val['fid_pos'])
xs,ys,zs = zip(*pts_local)
ax_fid.plot(xs,ys, 'o', label=module_id, color=color)
ax_fid.set_ylim((380,110))
ax_pot.set_ylim((40,-40))
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()
In [6]:
fig, ((ax_tl,ax_tr),(ax_bl,ax_br)) = plt.subplots(nrows=2, ncols=2,
sharex=True, sharey=True)
ideals = {'fid_TR': [-.39375, .9932, 0],
'fid_TL': [ .39375,9.0921, 0],
'fid_BL': [ .39375,-.9932, 0],
'fid_BR': [-.39375,-.9932, 0]}
fids = ['fid_TR', 'fid_TL', 'fid_BL', 'fid_BR']
for fid, ax in zip(fids, [ax_tr, ax_tl, ax_bl, ax_br]):
for color, module_id in zip(plt_cols,modules):
module = modules[module_id]
lb = module['BBM_fids'][fid]['fid_pos']
lh = module['HDI_fids'][fid]['fid_pos']
ideal = ideals[fid]
delta = [(float(dh)-float(db)-idl)*1000 for db, dh, idl in zip(lb, lh, ideal)]
ax.plot([delta[0]], [delta[1]], 'o', color=color, label=module_id)
ax.set_title('BBM-HDI '+fid.split('_')[1]+' offset')
ax.set_xlim((-250,250))
ax.set_ylim((250,-250))
fig.suptitle('Fiducial Offsets from ideal')
fig.text(0.5, 0.01, '$\Delta$x ($\mu$ m)', ha='center')
fig.text(0.0, 0.5, '$\Delta$y ($\mu$ m)', va='center', rotation='vertical')
fig.tight_layout()
plt.show()
In [7]:
def before(modules, date_str):
cut_date = datetime.strptime(date_str,'%d/%m/%Y')
for module_id, module in modules.items():
pot_date = datetime.strptime(module['date'],'%d/%m/%Y')
if pot_date < cut_date:
yield module_id, module
def after(modules, date_str):
cut_date = datetime.strptime(date_str,'%d/%m/%Y')
for module_id, module in modules.items():
pot_date = datetime.strptime(module['date'],'%d/%m/%Y')
if pot_date >= cut_date:
yield module_id, module
In [8]:
from scatter_hist import scatter_hist
def plot_offset(fig, modules):
xs = []
ys = []
for module_id, module in modules:
bbm_center = [float(x)*1000 for x in module['BBM_center']]
hdi_center = [float(x)*1000 for x in module['HDI_center']]
xs.append(hdi_center[0] - bbm_center[0])
ys.append(hdi_center[1] - bbm_center[1])
scatter_hist(xs, ys, fig, nbins=20, plot_mean=True, xlabel="X($\\mu$m)", ylabel="Y($\\mu$m)")
fixdate = '09/05/2016'
fig = plt.figure()
plot_offset(fig, before(modules, fixdate))
fig = plt.figure()
plot_offset(fig, after(modules, fixdate))
In [9]:
fig, (ax_pre, ax_post) = plt.subplots(nrows=1, ncols=2)
def histo2(ax, modules):
data = []
for module_id, module in modules:
rot_bbm = net_phi(module['BBM_orient'])
rot_hdi = net_phi(module['HDI_orient'])
data.append(abs(rot_bbm - rot_hdi))
hist, bins = np.histogram(data, bins=20, range=(0,.5))
width = 0.8 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
ax.bar(center, hist, align='center', width=width)
ax.set_xlim((0,.5))
ax.set_ylim((0,40))
label = "N={:d}\n$\mu=${:0.3f}$^\circ$\n$\sigma=${:0.3f}".format(len(data), np.mean(data), np.std(data))
ax.text(0.32, 12, label)
histo2(ax_pre, before(modules, fixdate))
histo2(ax_post, after(modules, fixdate))
plt.show()
In [10]:
fig, (ax_pre, ax_post) = plt.subplots(nrows=1, ncols=2)
def histo2(ax, modules):
data = []
for module_id, module in modules:
rot_bbm = net_phi(module['BBM_orient'])
rot_hdi = net_phi(module['HDI_orient'])
data.append(rot_hdi - rot_bbm)
hist, bins = np.histogram(data, bins=50, range=(-.5,.5))
width = 0.8 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
ax.bar(center, hist, align='center', width=width)
ax.set_xlim((-.5,.5))
ax.set_ylim((0,25))
label = "N={:d}\n$\mu=${:0.3f}$^\circ$\n$\sigma=${:0.3f}".format(len(data), np.mean(data), np.std(data))
ax.text(0.2, 20, label)
histo2(ax_pre, before(modules, fixdate))
histo2(ax_post, after(modules, fixdate))
plt.show()
In [11]:
fig, ((ax_h, ax_w), (ax_rh, ax_rw)) = plt.subplots(nrows=2, ncols=2)
ideal_width = 18410.00 # μm
ideal_height = 60869.95 # μm , actually average between left and right spacings(left is smaller)
heights = []
widths = []
rots = []
for module in modules.values():
fids = module['HDI_fids']
fid_tr = fids['fid_TR']['fid_pos']
fid_tl = fids['fid_TL']['fid_pos']
fid_bl = fids['fid_BL']['fid_pos']
fid_br = fids['fid_BR']['fid_pos']
def dist(fid1, fid2):
pairs = [(float(x), float(y)) for x,y in zip(fid1, fid2)]
return np.sqrt(sum((x-y)**2 for x, y in pairs[:2]))*1000
left_height = dist(fid_bl, fid_tl)
right_height = dist(fid_br, fid_tr)
# print("left height:{}\tright height:{}".format(left_height, right_height))
height = (left_height+right_height)/2 - ideal_height
heights.append(height)
top_width = dist(fid_tl, fid_tr)
bottom_width = dist(fid_bl, fid_br)
width = (top_width+bottom_width)/2 - ideal_width
widths.append(width)
rot_bbm = net_phi(module['BBM_orient'])
rot_hdi = net_phi(module['HDI_orient'])
rots.append(rot_hdi - rot_bbm)
# if(abs(height) < 40):
# print("{:10} - {:+.03f}".format(module['id'], height))
def histo(data, ax, xlabel, nbins, range_):
hist, bins = np.histogram(data, bins=nbins, range=range_)
width = 0.8 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
ax.bar(center, hist, align='center', width=width)
ax.set_xlabel(xlabel)
ax.set_xlim(range_)
histo(heights, ax_h, '$\Delta$height ($\mu$m)', 35, (-130,130))
histo(widths, ax_w, '$\Delta$width ($\mu$m)', 35, (-30,30))
ax_rh.plot(heights, rots, 'o')
ax_rh.set_xlabel('$\Delta$height ($\mu$m)')
ax_rh.set_ylabel('$\Delta\\theta$ (degrees)')
ax_rw.plot(widths, rots, 'o')
ax_rw.set_xlabel('$\Delta$width ($\mu$m)')
ax_rw.set_ylabel('$\Delta\\theta$ (degrees)')
fig.tight_layout()
plt.show()
In [12]:
figure, ((ax_h, ax_w), (ax_r, _)) = plt.subplots(nrows=2, ncols=2)
times = []
for module in modules.values():
date = module['date']
times.append(datetime.strptime(date, '%d/%m/%Y'))
xticks = [datetime(2016, i, 15) for i in range(3,7)]
xticklabels = [d.strftime("%b %d") for d in xticks]
ax_h.plot(times, heights, 'o')
ax_h.set_xticks(xticks)
ax_h.set_xticklabels(xticklabels)
ax_h.set_ylabel('$\Delta$height ($\mu$m)')
ax_w.plot(times, widths, 'o')
ax_w.set_xticks(xticks)
ax_w.set_xticklabels(xticklabels)
ax_w.set_ylabel('$\Delta$width ($\mu$m)')
ax_r.plot(times, rots, 'o')
ax_r.set_xticks(xticks); ax_r.set_xticklabels(xticklabels)
ax_r.set_ylabel('$\Delta$\\theta (degrees)')
fig.tight_layout()
In [13]:
ideal_fids = {'fid_TL': np.array([-8759.5, -24359.9, 0]),
'fid_TR': np.array([+8759.5, -32459.5, 0]),
'fid_BL': np.array([-8759.5, +32459.5, 0]),
'fid_BR': np.array([+8759.5, +32459.5, 0])}
def to_local_coords(center, orient, pos):
center = np.array([float(d) for d in center])
orient = Quaternion.Quat([float(d) for d in orient])
pos = np.array([float(d) for d in pos])
return orient.inv().transform @ (pos - center)
def get_fid_xy(module, fid):
center = module['HDI_center']
orient = module['HDI_orient']
pos = module['HDI_fids'][fid]['fid_pos']
local_pos = 1000*to_local_coords(center, orient, pos)
return (local_pos - ideal_fids[fid])[:2]
def is_numeric(number):
try:
int(number)
return True
except ValueError:
return False
fids_comp = []
fids_pci = []
for module_id, module in modules.items():
tl = get_fid_xy(module, 'fid_TL')
tr = get_fid_xy(module, 'fid_TR')
bl = get_fid_xy(module, 'fid_BL')
br = get_fid_xy(module, 'fid_BR')
if is_numeric(module_id[-2:]):
fids_comp.append((tl, tr, bl, br))
else:
fids_pci.append((tl, tr, bl, br))
figure, axs = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
axs = list(itertools.chain(*axs))
for ax, comp, pci in zip(axs, zip(*fids_comp), zip(*fids_pci)):
xs, ys = zip(*comp)
comp_mean = np.array((np.mean(xs), np.mean(ys)))
ax.scatter(xs, ys, c='b', s=20, marker='.')
ax.scatter([comp_mean[0]], [comp_mean[1]], c='b', s=50)
ax.text(comp_mean[0]+10, comp_mean[1], 'Compunetix', color='b')
xs, ys = zip(*pci)
pci_mean = np.array((np.mean(xs), np.mean(ys)))
ax.scatter(xs, ys, c='r', s=20, marker='.')
ax.scatter([pci_mean[0]], [pci_mean[1]], c='r', s=50)
ax.text(pci_mean[0]+10, pci_mean[1], 'PCI', color='r')
plot_center = (comp_mean + pci_mean) / 2
# ax.set_xlim((plot_center[0]-60,plot_center[0]+60))
# ax.set_ylim((plot_center[1]+40,plot_center[1]-40))
ax.set_xlim((-100,100))
ax.set_ylim((100,-100))
ax.set_aspect('equal')
figure.text(0.5, 0.01, '$\Delta$x ($\mu$ m)', ha='center')
figure.text(0.0, 0.5, '$\Delta$y ($\mu$ m)', va='center', rotation='vertical')
figure.tight_layout()
In [ ]: